import webpack from 'webpack';
import chalk from 'chalk';
import getWebpackConfig from '../getWebpackConfig';
import webpackDevServer, { Configuration } from 'webpack-dev-server';
import { getDevServerOutputDir, getWxConfig } from '../config';
import { getLocalIp } from '../utils';
import { tryPortStart } from '../helpers';

export default (wrapper = (a: Configuration) => a) => {
  const publicPath = '/api';
  const webpackConfig = getWebpackConfig({
    mode: 'development',
    publicPath,
  });
  const contentBase = getDevServerOutputDir();
  const wxConfig = getWxConfig();
  const serverWrapper = wxConfig.server || ((a: Configuration) => a);
  const configPort = wxConfig.port || 8020;
  webpackConfig.output!.path = contentBase;
  // webpackConfig.module.rules.push({ enforce: "pre", test: /\.js$/, loader: "source-map-loader" });
  const compiler = webpack(webpackConfig);
  const devServerOptions = {
    contentBase,
    hot: true,
    inline: true,
    publicPath,
    historyApiFallback: true,
    port: configPort,
    open: false,
    noInfo: true,
    https: false,
    host: '0.0.0.0',
    stats: {
      assets: true,
      chunks: false,
      // 添加 namedChunkGroups 信息
      chunkGroups: false,
      // 将构建模块信息添加到 chunk 信息
      chunkModules: false,
      // 添加 chunk 和 chunk merge 来源的信息
      chunkOrigins: false,
      // 添加构建模块信息
      modules: false,
      colors: true,
      reasons: false,
      children: false,
    },
  };
  const callTempOptions = wrapper(devServerOptions) || devServerOptions;
  const finalOptions = serverWrapper(callTempOptions) || callTempOptions;
  const port = finalOptions.port;
  const host = finalOptions.host;
  const https = finalOptions.https;
  const server = new webpackDevServer(compiler as any, finalOptions);

  tryPortStart({
    port,
    host,
    callback: (err, port, host) => {
      if (err) {
        console.error(err);
        process.exit(-1);
        return;
      }
      server.listen(port, host, (err) => {
        if (err) {
          console.error('ERROR:', err);
          return;
        }
        const protocol = https ? 'https' : 'http';
        const loopback = host === '0.0.0.0' ? 'localhost' : host;
        const localIP = getLocalIp();
        console.log(chalk.bgGreen(chalk.black(' DONE ')) + chalk.green(' success !'));
        console.log('Project Running at:');
        console.log(`    Local: ${chalk.cyan(`${protocol}://${loopback}:${port}/`)}`);
        if (localIP) {
          console.log(`      LAN: ${chalk.cyan(`${protocol}://${localIP}:${port}/`)}`);
        }
      });
    },
  });
  return server;
};
